
#include "main.h"


vu32 g_vu32SysTickCount = 0;
vu32 g_vu32SysTickSecond = 0;
u8 g_u8CurState = STATE_UNKNOWN;
u8 g_u8OsType = OSTYPE_UNKNOWN;
u8 g_u8TestCode = 0;
#if		defined(BSP_DEVICE_TOUCH)
u8 g_u8MyAddr = DEV_TOUCH;
u32 g_u32BuzzerDelay = 0;
USB_OTG_CORE_HANDLE g_UsbOtgDevice;
TOUCHCONFIG_DATA g_TCD;
#elif	defined(BSP_DEVICE_CAMERA)
u8 g_u8MyAddr = DEV_CAMERA1;
CAMERACONFIG_DATA g_CCD;
#endif	//BSP_DEVICE_xxx

static void jumpToApplication(void);


static STATE_PROC _CurStateProc = NULL;

static void procState(u8 state);
static void stateIapInit(u8 state);
static void stateIapUpgrade(u8 state);


int main()
{
	time_t tBuildTime = Util_GetBuildTime();
	u32 uDelay_ms = 0;
	u16 uData, uTotalSize = 0;

	if (SysTick_Config(SystemCoreClock / 1000)) /* 1msec */
		while (1);

	/* NVIC_PriorityGroup_2 : 0~3, 0~3 */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	Uart_Init();
#if		defined(BSP_DEVICE_TOUCH)
	printf("\r\n <<< Iap_Touch Controller Start >>> \r\n");
#elif	defined(BSP_DEVICE_CAMERA)
	printf("\r\n <<< Iap_Camera Controller Start >>> \r\n");
#endif	//BSP_DEVICE_xxx
	g_u8MyAddr = Util_BoardAddr();
	printf(">    BoardAddr : 0x%02X\r\n", g_u8MyAddr);
	printf("> StartAddress : 0x%X\r\n", SCB->VTOR);
	printf("> VersionInfo  : 0x%04X\r\n", MODULE_VERSION);
	printf("> BuildDate    : %s\r\n", ctime(&tBuildTime));

	Led_Init();
	FLASH_If_Init();
	EE_Init();

	EE_ReadVariable(g_VirtAddVarTab[IAP_SAVE_APP_CHECK], &uData);
	printf(">      IAP_SAVE_APP_CHECK : 0x%X\r\n", uData);
	EE_ReadVariable(g_VirtAddVarTab[IAP_SAVE_APP_TOTAL_SIZE], &uTotalSize);
	printf("> IAP_SAVE_APP_TOTAL_SIZE : %d\r\n\r\n", uTotalSize);

	if ((0x1234 == uData) && uTotalSize)
	{
		if (0 == Util_FirmwareUpdate(SCB->VTOR, uTotalSize))
		{
			uData = 0;
			EE_WriteVariable(g_VirtAddVarTab[IAP_SAVE_APP_CHECK], uData);
			EE_WriteVariable(g_VirtAddVarTab[IAP_SAVE_APP_TOTAL_SIZE], uData);

			uDelay_ms = g_vu32SysTickCount + 1000;
			while (uDelay_ms <= g_vu32SysTickCount);
			NVIC_SystemReset();
		}
	}

	if (!Util_IsResetWWDG())
	{
		jumpToApplication();
		while (1);
	}

#if		defined(BSP_DEVICE_TOUCH)
	Usb_Init();
	USBD_Init(&g_UsbOtgDevice, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_HID_cb, &USR_cb);
#endif	//BSP_DEVICE_TOUCH

	g_u8CurState = STATE_IAP_INIT;
	while (1)
	{
		Uart_PktProc();
#if		defined(BSP_DEVICE_TOUCH)
		Usb_PktProc();
#endif	//BSP_DEVICE_TOUCH
		procState(g_u8CurState);
		if (uDelay_ms <= g_vu32SysTickCount)
		{
			Led_Toggle(eLED_STATUS);
			uDelay_ms = g_vu32SysTickCount + 1000;
		}
	}
}

static void procState(u8 state)
{
	static u8 _oldState = STATE_UNKNOWN;

	if (_oldState != state)
	{
		switch (state)
		{
		case STATE_IAP_INIT:
			_CurStateProc = stateIapInit;
			break;
		case STATE_IAP_UPGRADE:
			_CurStateProc = stateIapUpgrade;
			break;

		default:
			printf("!!! stateChange(%d -> %d(Unknown))\r\n", _oldState, state);
			Util_ResetWWDG();
			return;
		}
		#if	DBG_MSG_IAP
		printf("stateChange(%d -> %d)\r\n", _oldState, state);
		#endif	//DBG_MSG_IAP
		_oldState = state;
	}

	_CurStateProc(state);
}

static void stateIapInit(u8 state)
{
#if		defined(BSP_DEVICE_CAMERA)
	static u32 _dwDelay_ms = 0;
	if (_dwDelay_ms <= g_vu32SysTickCount)
	{
		Uart_PktEvt(eUART_TOUCH, EVT_CAMERA_INIT, DEV_CAMERA1, sizeof(g_u8CurState), (u8 *)&g_u8CurState);
		#if	DBG_MSG_IAP
		printf("EVT_CAMERA_IAP_INIT(%d)\r\n", g_vu32SysTickCount);
		#endif	//DBG_MSG_IAP

		_dwDelay_ms = g_vu32SysTickCount + 1000;
	}
#endif	//BSP_DEVICE_CAMERA
}
static void stateIapUpgrade(u8 state)
{
}


static void jumpToApplication(void)
{
	u32 JumpAddress = *(__IO uint32_t*)(APP_START_ADDRESS + 4);
	printf(" <<< jumpToApplication(%X, %X) >>> \r\n\r\n", APP_START_ADDRESS, JumpAddress);

	pFunction Jump_To_Application = (pFunction)JumpAddress;
	__set_MSP(*(__IO uint32_t*)APP_START_ADDRESS);
	Jump_To_Application();
}

